import React, { useContext, useEffect, useState } from 'react';
import locale from './locale';
import useLocale from '@/utils/useLocale';
import {
  Grid,
  Card,
  Skeleton,
  DatePicker,
  Select,
  Empty,
} from '@arco-design/web-react';
import ECharts from '@/components/Echarts';
import PngEmpty from '@/assets/empty.png';
import IconCases from './assets/cases.png';
import IconProgress from './assets/progress.png';
import IconClosed from './assets/closed.png';
import IconEntities from './assets/entities.png';
import IconCasesDark from './assets/cases-dark.png';
import IconProgressDark from './assets/progress-dark.png';
import IconClosedDark from './assets/closed-dark.png';
import IconEntitiesDark from './assets/entities-dark.png';
import styles from './style/index.module.less';
import {
  ComplainantRoles,
  Search,
  Top10Assignees,
  Top5Entities,
  Top5Source,
  Top5ViolationTypes,
  ViolationStatus,
} from '@/api/modules/dashboard';
import {
  Dashboard,
  ViolationStatus as ViolationStatusReq,
} from '@/api/interface/dashboard';
import { GlobalContext } from '@/context';
import {
  newCasesOptionsFn,
  violationStatusFn,
  entitiesFn,
  sourcesFn,
  complainantFn,
  violationTypesFn,
  assigneesFn,
} from './config';
import dayjs from 'dayjs';
import { EnumsRes } from '@/api/interface';
import { Enums } from '@/api/modules';
import { entityGet } from '@/api/modules/entity';

const { Row, Col } = Grid;
const { MonthPicker } = DatePicker;
const Option = Select.Option;

function DashboardPage() {
  const t = useLocale(locale);

  const { lang, rtl, theme } = useContext(GlobalContext);

  const isDark = theme === 'dark' ? true : false;

  const currentDate = dayjs().format('YYYY-MM');

  const [data, setData] = useState<Partial<Dashboard>>({
    topBar: { totalCases: 0, inProgress: 0, closed: 0, totalEntities: 0 },
    newCases: { lastYear: [], thisYear: [] },
  });

  useEffect(() => {
    getEntity();
    getEnums();
  }, []);

  const [entity, setEntity] = useState<any[]>([]);
  const [entityValue, setEntityValue] = useState<string | undefined>(undefined);
  const getEntity = async () => {
    const { data } = await entityGet({ active: true });
    setEntity(data);
  };

  const [sourceEnums, setSourceEnums] = useState<EnumsRes[] | any[]>([]);
  const [sourceValue, setSourceValue] = useState<string>('');
  const getEnums = async () => {
    const { data } = await Enums({ type: 'SourceEnums' });
    setSourceEnums(data);
    sourceChange(data.map((item) => item.key));
  };

  const sourceChange = (val: string[]) => {
    const sourceKey = val.length
      ? val?.join(',')
      : sourceEnums.map((item) => item.key)?.join(',');
    setSourceValue(sourceKey);
  };

  useEffect(() => {
    if (!sourceValue) return;
    getData(sourceValue, entityValue);
  }, [sourceValue, entityValue]);

  const getData = (sourceKey: string, entityId: string) => {
    getDashboardData(sourceKey, entityId);
    getViolationStatus(violationStatusDate, sourceKey, entityId);
    getTop5Entities(top5EntitiesDate, sourceKey, entityId);
    getTop5Source(top5SourceDate, sourceKey, entityId);
    getComplainantRoles(complainantRolesDate, sourceKey, entityId);
    getTop5ViolationTypes(top5ViolationTypesDate, sourceKey, entityId);
    getTop10Assignees(top10AssigneesDate, sourceKey, entityId);
  };

  const [loading, setLoading] = useState(true);
  const getDashboardData = async (
    source: string = sourceValue,
    entityId: string
  ) => {
    try {
      setLoading(true);
      const { data } = await Search({ source, entityId });
      setData(data);
    } finally {
      setLoading(false);
    }
  };

  const [violationStatusLoading, setViolationStatusLoading] = useState(true);
  const [violationStatusDate, setViolationStatusDate] = useState(currentDate);
  const [violationStatus, setViolationStatus] = useState<
    Dashboard['violationStatus']
  >([]);
  const getViolationStatus = async (
    date: string,
    source: string = sourceValue,
    entityId: string = entityValue
  ) => {
    try {
      setViolationStatusLoading(true);
      setViolationStatusDate(date);
      const { data } = await ViolationStatus({
        year: date.substring(0, 4),
        month: date.substring(5, 7),
        entityId,
        source,
      });
      setViolationStatus(JSON.stringify(data) === '{}' ? [] : data);
    } finally {
      setViolationStatusLoading(false);
    }
  };
  const [violationStatusSum, setViolationStatusSum] = useState<number>(0);
  useEffect(() => {
    const sum = (prev: number, cur: ViolationStatusReq) =>
      prev +
      Number(
        cur.assigned +
          cur.closed +
          cur.inProgress +
          cur.transferred +
          cur.underReview
      );
    const num = violationStatus.reduce(sum, 0);
    setViolationStatusSum(num);
  }, [violationStatus]);

  const [top5EntitiesLoading, setTop5EntitiesLoading] = useState(true);
  const [top5EntitiesDate, setTop5EntitiesDate] = useState(currentDate);
  const [top5Entities, setTop5Entities] = useState<Dashboard['top5Entities']>(
    []
  );
  const getTop5Entities = async (
    date: string,
    source: string = sourceValue,
    entityId: string = entityValue
  ) => {
    try {
      setTop5EntitiesLoading(true);
      setTop5EntitiesDate(date);
      const { data } = await Top5Entities({
        year: date.substring(0, 4),
        month: date.substring(5, 7),
        entityId,
        source,
      });
      setTop5Entities(JSON.stringify(data) === '{}' ? [] : data);
    } finally {
      setTop5EntitiesLoading(false);
    }
  };

  const [top5SourceLoading, setTop5SourceLoading] = useState(true);
  const [top5SourceDate, setTop5SourceDate] = useState(currentDate);
  const [top5Source, setTop5Source] = useState<Dashboard['top5Source']>([]);
  const getTop5Source = async (
    date: string,
    source: string = sourceValue,
    entityId: string = entityValue
  ) => {
    try {
      setTop5SourceLoading(true);
      setTop5SourceDate(date);
      const { data } = await Top5Source({
        year: date.substring(0, 4),
        month: date.substring(5, 7),
        entityId,
        source,
      });
      setTop5Source(JSON.stringify(data) === '{}' ? [] : data);
    } finally {
      setTop5SourceLoading(false);
    }
  };

  const [complainantRolesLoading, setComplainantRolesLoading] = useState(true);
  const [complainantRolesDate, setComplainantRolesDate] = useState(currentDate);
  const [complainantRoles, setComplainantRoles] = useState<
    Dashboard['complainantRoles']
  >([]);
  const getComplainantRoles = async (
    date: string,
    source: string = sourceValue,
    entityId: string = entityValue
  ) => {
    try {
      setComplainantRolesLoading(true);
      setComplainantRolesDate(date);
      const { data } = await ComplainantRoles({
        year: date.substring(0, 4),
        month: date.substring(5, 7),
        entityId,
        source,
      });
      setComplainantRoles(JSON.stringify(data) === '{}' ? [] : data);
    } finally {
      setComplainantRolesLoading(false);
    }
  };

  const [top5ViolationTypesLoading, setTop5ViolationTypesLoading] =
    useState(true);
  const [top5ViolationTypesDate, setTop5ViolationTypesDate] =
    useState(currentDate);
  const [top5ViolationTypes, setTop5ViolationTypes] = useState<
    Dashboard['top5ViolationTypes']
  >([]);
  const getTop5ViolationTypes = async (
    date: string,
    source: string = sourceValue,
    entityId: string = entityValue
  ) => {
    try {
      setTop5ViolationTypesLoading(true);
      setTop5ViolationTypesDate(date);
      const { data } = await Top5ViolationTypes({
        year: date.substring(0, 4),
        month: date.substring(5, 7),
        entityId,
        source,
      });
      setTop5ViolationTypes(JSON.stringify(data) === '{}' ? [] : data);
    } finally {
      setTop5ViolationTypesLoading(false);
    }
  };

  const [top10AssigneesLoading, setTop10AssigneesLoading] = useState(true);
  const [top10AssigneesDate, setTop10AssigneesDate] = useState(currentDate);
  const [top10Assignees, setTop10Assignees] = useState<
    Dashboard['top10Assignees']
  >([]);
  const getTop10Assignees = async (
    date: string,
    source: string = sourceValue,
    entityId: string = entityValue
  ) => {
    try {
      setTop10AssigneesLoading(true);
      setTop10AssigneesDate(date);
      const { data } = await Top10Assignees({
        year: date.substring(0, 4),
        month: date.substring(5, 7),
        entityId,
        source,
      });
      setTop10Assignees(JSON.stringify(data) === '{}' ? [] : data);
    } finally {
      setTop10AssigneesLoading(false);
    }
  };

  const total = [
    {
      icon: IconCases,
      icon_dark: IconCasesDark,
      title: t['dashboard.cases'],
      count: data.topBar?.totalCases,
    },
    {
      icon: IconProgress,
      icon_dark: IconProgressDark,
      title: t['dashboard.progress'],
      count: data.topBar?.inProgress,
    },
    {
      icon: IconClosed,
      icon_dark: IconClosedDark,
      title: t['dashboard.closed'],
      count: data.topBar?.closed,
    },
    {
      icon: IconEntities,
      icon_dark: IconEntitiesDark,
      title: t['dashboard.entities'],
      count: data.topBar?.totalEntities,
    },
  ];

  return (
    <div className={styles['overview']}>
      {sourceValue && (
        <Select
          allowClear
          showSearch
          onChange={(value) => setEntityValue(value)}
          placeholder={t['dashboard.entity.placeholder']}
          className={styles['overview-select']}
          style={lang === 'en-US' ? { right: '256px' } : { left: '256px' }}
          triggerProps={{
            autoAlignPopupWidth: false,
            autoAlignPopupMinWidth: true,
          }}
          filterOption={(inputValue, option) => {
            return (
              option.props.children
                .toLowerCase()
                .indexOf(inputValue.toLowerCase()) >= 0
            );
          }}
        >
          {entity.map((option, index) => (
            <Option key={index} value={option?.id}>
              {option[lang === 'en-US' ? 'name' : 'nameAr']}
            </Option>
          ))}
        </Select>
      )}

      {sourceValue && (
        <Select
          onChange={(value) => {
            if (value.length === 1) {
              const source = [...sourceEnums];
              source.find((a) => a.key == value[0]).disabled = true;
              setSourceEnums(() => source);
            }
            if (value.length > 1) {
              const source = [...sourceEnums].map((a) => ({
                ...a,
                disabled: false,
              }));
              setSourceEnums(() => source);
            }
            sourceChange(value);
          }}
          defaultValue={sourceValue.split(',')}
          mode="multiple"
          maxTagCount={2}
          placeholder={t['dashboard.source.placeholder']}
          className={styles['overview-select']}
          triggerProps={{
            autoAlignPopupWidth: false,
            autoAlignPopupMinWidth: true,
          }}
          style={lang === 'en-US' ? { right: '20px' } : { left: '20px' }}
        >
          {sourceEnums.map((option, index) => (
            <Option key={index} value={option.key} disabled={option.disabled}>
              {option.value[lang === 'en-US' ? 'en' : 'ar']}
            </Option>
          ))}
        </Select>
      )}

      <Card className={styles['overview-total']}>
        <Row>
          {total.map((item) => {
            return (
              <Col flex={1} key={item.title}>
                <div className={styles['total-item']}>
                  <img
                    src={isDark ? item.icon_dark : item.icon}
                    className={styles['total-icon']}
                  ></img>
                  <div>
                    <Skeleton
                      loading={loading}
                      text={{ rows: 2, width: 60 }}
                      animation
                    >
                      <div className={styles['total-count']}>{item.count}</div>
                      <div className={styles['total-title']}>{item.title}</div>
                    </Skeleton>
                  </div>
                </div>
              </Col>
            );
          })}
        </Row>
      </Card>

      <Card className={styles['overview-cases']} bodyStyle={{ padding: 0 }}>
        <Skeleton
          loading={loading}
          text={{ rows: 13 }}
          style={{ padding: '20px' }}
          animation
        >
          <span className={styles['cases-title']}>
            {t['dashboard.cases.title']}
          </span>
          <div className={styles['cases-echarts']}>
            {data.newCases.thisYear.length === 0 ? (
              <div className={styles['empty']} style={{ height: 410 }}>
                <Empty
                  icon={
                    <img
                      style={{ width: 200, height: 'auto' }}
                      src={PngEmpty}
                    />
                  }
                />
              </div>
            ) : (
              <ECharts
                height={410}
                option={newCasesOptionsFn(data.newCases, isDark, rtl)}
              />
            )}
          </div>
        </Skeleton>
      </Card>

      <Row gutter={[15, 15]}>
        <Col xl={12} lg={12} md={12} sm={24} xs={24}>
          <Card
            title={t['dashboard.status.title']}
            bodyStyle={{ padding: 0 }}
            extra={
              <MonthPicker
                style={{ width: 100 }}
                allowClear={false}
                defaultValue={currentDate}
                disabledDate={(current) => current.isAfter(dayjs())}
                onChange={(val) => getViolationStatus(val)}
              />
            }
          >
            <Skeleton
              loading={violationStatusLoading}
              text={{ rows: 10 }}
              style={{ padding: '20px' }}
              animation
            >
              {violationStatusSum !== 0 ? (
                <ECharts
                  height={344}
                  option={violationStatusFn(violationStatus, isDark, rtl, t)}
                />
              ) : (
                <div className={styles['empty']} style={{ height: 344 }}>
                  <Empty
                    icon={
                      <img
                        style={{ width: 200, height: 'auto' }}
                        src={PngEmpty}
                      />
                    }
                  />
                </div>
              )}
            </Skeleton>
          </Card>
        </Col>
        <Col xl={12} lg={12} md={12} sm={24} xs={24}>
          <Card
            title={t['dashboard.entities.title']}
            bodyStyle={{ padding: 0 }}
            extra={
              <MonthPicker
                style={{ width: 100 }}
                allowClear={false}
                defaultValue={currentDate}
                disabledDate={(current) => current.isAfter(dayjs())}
                onChange={(val) => getTop5Entities(val)}
              />
            }
          >
            <Skeleton
              loading={top5EntitiesLoading}
              text={{ rows: 10 }}
              style={{ padding: '20px' }}
              animation
            >
              {top5Entities && top5Entities.length !== 0 ? (
                <ECharts
                  height={344}
                  option={entitiesFn(top5Entities, isDark, rtl)}
                />
              ) : (
                <div className={styles['empty']} style={{ height: 344 }}>
                  <Empty
                    icon={
                      <img
                        style={{ width: 200, height: 'auto' }}
                        src={PngEmpty}
                      />
                    }
                  />
                </div>
              )}
            </Skeleton>
          </Card>
        </Col>
        <Col xl={12} lg={12} md={12} sm={24} xs={24}>
          <Card
            title={t['dashboard.sources.title']}
            bodyStyle={{ padding: 0 }}
            extra={
              <MonthPicker
                style={{ width: 100 }}
                allowClear={false}
                defaultValue={currentDate}
                disabledDate={(current) => current.isAfter(dayjs())}
                onChange={(val) => getTop5Source(val)}
              />
            }
          >
            <Skeleton
              loading={top5SourceLoading}
              text={{ rows: 10 }}
              style={{ padding: '20px' }}
              animation
            >
              {top5Source && top5Source.length !== 0 ? (
                <ECharts
                  height={344}
                  option={sourcesFn(top5Source, isDark, rtl)}
                />
              ) : (
                <div className={styles['empty']} style={{ height: 344 }}>
                  <Empty
                    icon={
                      <img
                        style={{ width: 200, height: 'auto' }}
                        src={PngEmpty}
                      />
                    }
                  />
                </div>
              )}
            </Skeleton>
          </Card>
        </Col>
        <Col xl={12} lg={12} md={12} sm={24} xs={24}>
          <Card
            title={t['dashboard.complainant.title']}
            bodyStyle={{ padding: 0 }}
            extra={
              <MonthPicker
                style={{ width: 100 }}
                allowClear={false}
                defaultValue={currentDate}
                disabledDate={(current) => current.isAfter(dayjs())}
                onChange={(val) => getComplainantRoles(val)}
              />
            }
          >
            <Skeleton
              loading={complainantRolesLoading}
              text={{ rows: 10 }}
              style={{ padding: '20px' }}
              animation
            >
              {complainantRoles && complainantRoles.length !== 0 ? (
                <ECharts
                  height={344}
                  option={complainantFn(complainantRoles, isDark, rtl)}
                />
              ) : (
                <div className={styles['empty']} style={{ height: 344 }}>
                  <Empty
                    icon={
                      <img
                        style={{ width: 200, height: 'auto' }}
                        src={PngEmpty}
                      />
                    }
                  />
                </div>
              )}
            </Skeleton>
          </Card>
        </Col>
        <Col xl={12} lg={12} md={12} sm={24} xs={24}>
          <Card
            title={t['dashboard.types.title']}
            bodyStyle={{ padding: 0 }}
            extra={
              <MonthPicker
                style={{ width: 100 }}
                allowClear={false}
                defaultValue={currentDate}
                disabledDate={(current) => current.isAfter(dayjs())}
                onChange={(val) => getTop5ViolationTypes(val)}
              />
            }
          >
            <Skeleton
              loading={top5ViolationTypesLoading}
              text={{ rows: 10 }}
              style={{ padding: '20px' }}
              animation
            >
              {top5ViolationTypes && top5ViolationTypes.length !== 0 ? (
                <ECharts
                  height={344}
                  option={violationTypesFn(top5ViolationTypes, isDark, rtl)}
                />
              ) : (
                <div className={styles['empty']} style={{ height: 344 }}>
                  <Empty
                    icon={
                      <img
                        style={{ width: 200, height: 'auto' }}
                        src={PngEmpty}
                      />
                    }
                  />
                </div>
              )}
            </Skeleton>
          </Card>
        </Col>
        <Col xl={12} lg={12} md={12} sm={24} xs={24}>
          <Card
            title={t['dashboard.assignees.title']}
            bodyStyle={{ padding: 0 }}
            extra={
              <MonthPicker
                style={{ width: 100 }}
                allowClear={false}
                defaultValue={currentDate}
                disabledDate={(current) => current.isAfter(dayjs())}
                onChange={(val) => getTop10Assignees(val)}
              />
            }
          >
            <Skeleton
              loading={top10AssigneesLoading}
              text={{ rows: 10 }}
              style={{ padding: '20px' }}
              animation
            >
              {top10Assignees && top10Assignees.length !== 0 ? (
                <ECharts
                  height={344}
                  option={assigneesFn(top10Assignees, isDark, rtl)}
                />
              ) : (
                <div className={styles['empty']} style={{ height: 344 }}>
                  <Empty
                    icon={
                      <img
                        style={{ width: 200, height: 'auto' }}
                        src={PngEmpty}
                      />
                    }
                  />
                </div>
              )}
            </Skeleton>
          </Card>
        </Col>
      </Row>
    </div>
  );
}

export default DashboardPage;
